#include "TestComponents.hpp"
#include "MathHelper.hpp"
#include <math.h>

TestComponents::TestComponents() {
    
}

TestComponents::~TestComponents() {
    
}


void TestComponents::Initialize() {
    
    world.AddSystem(&renderer);
    world.AddSystem(&hierarchy);
    world.AddSystem(&physics);
    
    
    
    
    
    
    camera.AddComponent<Transform>()->Position = Vector3(5*2.5f * 0.5f,5,30);
    camera.AddComponent<Camera>()->Aspect = 768.0f / 1024.0f;
    
    world.AddGameObject(&camera);
    
    
    btCollisionShape* groundShape = new btBoxShape(btVector3(100,0.1f,100));
	btRigidBody::btRigidBodyConstructionInfo* groundDefinition = new btRigidBody::btRigidBodyConstructionInfo(0,0,groundShape,btVector3(0,0,0));
    
	GameObject* ground = new GameObject();
	ground->AddComponent<Transform>()->Position = Vector3(0,0,0);
	ground->AddComponent<RigidBody>()->Body = groundDefinition;
    
	world.AddGameObject(ground);
    
        
    
    cubeMesh.AddCube(0, 1, Colour::White());
    
    
    for (int y=0; y<10; y++) {
		for(int x=0; x<((y & 1) ? 4 : 5); x++) {
			GameObject* cube = CreatePhysicsCube(Vector3(x*2.5f+((y & 1) ? 1.25f : 0),1+y*2.005f,-10));
			world.AddGameObject(cube);
		}
	}
    
    camera.GetComponent<Transform>()->Rotation = Quaternion::Create(ToRadians(5), Vector3(1,0,0));
    
    light = new GameObject();
    light->AddComponent<Light>();
    light->AddComponent<Transform>();
    
    world.AddGameObject(light);
    
}

static float rotationLight = 0;

void TestComponents::Update(float dt) {
    
    rotationLight+=dt * 0.01f;
    
    light->GetComponent<Transform>()->Position = Vector3(sinf(rotationLight) * 10,0,-10+cosf(rotationLight) * 10);
    
    physics.Update(dt * 0.02f);
    
   
}

void TestComponents::Render() {
    
    
    
    //renderer.Render(&camera, Box(0,0,768,1024));
    renderer.Render(&camera, Box(0,0,320,480));
    
    
    
}

void TestComponents::Fire() {
    
    
    Vector3 position = camera.GetComponent<Transform>()->World.GetValue()->TransformPosition(Vector3(0,0,0));
    
	GameObject* go = CreatePhysicsCube(position);
	world.AddGameObject(go);
    
	go->GetComponent<RigidBody>()->ApplyImpulse(camera.GetComponent<Transform>()->World.GetValue()->TransformVector(Vector3(0,0,-50)), 0);
    

    
    
}


GameObject* TestComponents::CreateCube(Vector3 position) {
	GameObject* go = new GameObject();
    
	go->AddComponent<Hierarchy>();
	go->AddComponent<Transform>()->Position = position;
	go->AddComponent<Renderable>()->Mesh = &cubeMesh;

    
	return go;
}

GameObject* TestComponents::CreatePhysicsCube(Vector3 position) {
	GameObject* go = CreateCube(position);
    
	btCollisionShape* boxShape = new btBoxShape(btVector3(1,1,1));
    btVector3 vec(1,1,1);
	boxShape->calculateLocalInertia(1, vec);
    
	btRigidBody::btRigidBodyConstructionInfo* info = new btRigidBody::btRigidBodyConstructionInfo(1,0,boxShape,btVector3(1,1,1));
    
	go->AddComponent<RigidBody>()->Body = info;
	
	return go;
}




